package com.zyso.config;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.TypeReference;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.zyso.pojo.Site;
import com.zyso.pojo.SiteCommit;
import com.zyso.pojo.SiteEntries;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.lionsoul.ip2region.xdb.Searcher;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Slf4j
@Configuration
public class ZYSoConfig {

    @Value("${zyso.sites.path}")
    private String path;

    @Bean
    public LinkedHashMap<Integer, Site> sitesResource() {
        try (InputStream inputStream = new URL(path).openStream()) {
            String result = JSON.parseObject(inputStream, String.class);
            Map<String, String> subEntriesMap = JSON.parseObject(result, new TypeReference<Map<String, String>>() {
            });
            String entries = subEntriesMap.get("entries");
            SiteEntries siteEntries = JSON.parseObject(entries, SiteEntries.class);
            List<Site> list = JSON.parseArray(siteEntries.getContent(), Site.class);
            LinkedHashMap<Integer, Site> map = list.stream().collect(Collectors.toMap(Site::getId, e -> e, (o1, o2) -> o2, LinkedHashMap::new));
            SiteCommit entriesCommit = siteEntries.getCommit();
            log.info("--site init-- size : {} commit : {} {}", list.size(), entriesCommit.getCreated_at(), entriesCommit.getTime_from_now());
            return map;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Bean
    public ThreadPoolExecutor threadPoolExecutor() {
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 20, 30L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(1000), new ThreadFactoryBuilder().setNameFormat("zyso-pool-").build(), new ThreadPoolExecutor.DiscardPolicy());
        log.info("--zyso pool executor init--");
        return threadPoolExecutor;
    }

    @Bean
    public Searcher searcher() {
        try (InputStream inputStream = new ClassPathResource("ip2region.xdb").getInputStream()) {
            byte[] byteArray = IOUtils.toByteArray(inputStream);
            Searcher searcher = Searcher.newWithBuffer(byteArray);
            log.info("--searcher init--");
            return searcher;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

}
